let interceptorsReq = []; // 拦截请求的函数集合
let interceptorsReqError = []; // 拦截请求错误的函数集合
let interceptorsRes = []; // 拦截响应的处理函数集合
let interceptorsResError = []; // 拦截响应错误的函数集合

const originFetch = window.fetch;

function cfetch(url, options = {}) {
  interceptorsReq.forEach((item) => {
    options = item(options);
  });

  return new Promise((resolve, reject) => {
    originFetch(url, options)
      .then((res) => {
        interceptorsRes.forEach((item) => {
          // 拦截器对响应结果做处理，把处理后的结果返回给响应结果。
          res = item(res);
        });
        // 将拦截器处理后的响应结果resolve出去
        resolve(res);
      })
      .catch((err) => {
        // interceptorsResError是拦截响应错误结果的拦截处理函数集合
        interceptorsResError.forEach((item) => {
          // 拦截器对响应错误结果做处理，把处理后的结果返回给响应结果。
          err = item(err);
        });
        reject(err);
      });
  });
}

// interceptors拦截器提供request和response两种拦截器功能。
// 可以通过request和response的use方法来绑定两种拦截器的处理函数。
// use方法接收两个参数，参数为一个callback函数，callback函数用来作为拦截器的成功处理函数，errorCallback作为错误处理函数
// request.use方法会把callback放在interceptorsReq中，等待执行。
// response.use方法会把callback放在interceptorsRes中，等待执行。
// 拦截器的处理函数callback接收一个参数。
// request拦截器的callback接收的是请求发起前的config；
// response拦截器的callback接收的是网络请求的response结果。
const interceptors = {
  request: {
    use(callback, errorCallback) {
      interceptorsReq.push(callback);
      errorCallback && interceptorsReqError.push(errorCallback);
    },
  },
  response: {
    use(callback, errorCallback) {
      interceptorsRes.push(callback);
      errorCallback && interceptorsResError.push(errorCallback);
    },
  },
};

export { cfetch, interceptors };
